 #手动实现RNN的实例
import tensorflow.compat.v1 as tf
import numpy as np
tf.set_random_seed(777)

n_inputs = 3 #每个样本3个特征
n_neurons = 5 #隐藏状态，神经元个数

X0 = tf.placeholder(tf.float32, [None, n_inputs])
X1 = tf.placeholder(tf.float32, [None, n_inputs])
X2 = tf.placeholder(tf.float32, [None, n_inputs])
X3 = tf.placeholder(tf.float32, [None, n_inputs])

# 由于Wx要和X相乘，故低维是n_inputs
Wx = tf.Variable(tf.random_normal(shape=[n_inputs, n_neurons], dtype=tf.float32))
# 低维，高维都是n_neurons，为了使得输出也是hidden state的深度
# 这样下一次才可以继续运算
Wy = tf.Variable(tf.random_normal(shape=[n_neurons, n_neurons], dtype=tf.float32))
b = tf.Variable(tf.zeros([1, n_neurons], dtype=tf.float32))

# Y0，Y1都是4*5大小
# Y0初始化为0，初始时没有记忆
Y00 = tf.constant(np.zeros([5, 5]), dtype=tf.float32)
Y0 = tf.tanh(tf.matmul(Y00, Wy) + tf.matmul(X0, Wx) + b)
# 把上一轮输出Y0也作为输入
Y1 = tf.tanh(tf.matmul(Y0, Wy) + tf.matmul(X1, Wx) + b)
Y2 = tf.tanh(tf.matmul(Y1, Wy) + tf.matmul(X2, Wx) + b)
Y3 = tf.tanh(tf.matmul(Y2, Wy) + tf.matmul(X3, Wx) + b)

# 4是mini-batch数目
X0_batch = np.array([[0, 1, 2], [3, 4, 5], [6, 7, 8], [9, 0, 1], [0, 1, 2]]) # t = 0
X1_batch = np.array([[9, 8, 7], [0, 0, 0], [6, 5, 4], [3, 2, 1], [9, 8, 7]]) # t = 1
X2_batch = X0_batch.copy()
X3_batch = X1_batch.copy()

with tf.Session() as sess:
    sess.run(tf.global_variables_initializer())
    Y0_val, Y1_val, Y2_val, Y3_val = sess.run([Y0, Y1, Y2, Y3], feed_dict={X0: X0_batch, X1: X1_batch, X2: X2_batch, X3: X3_batch})

print("Y0_val:\n",Y0_val)
print("Y1_val:\n",Y1_val)
print("Y2_val:\n",Y2_val)
print("Y3_val:\n",Y3_val)

'''
Y0_val:
 [[ 0.98001486  0.9998944  -0.95606947 -0.59023184  0.9938589 ]
 [ 1.          1.         -1.         -0.9999806   0.9999991 ]
 [ 1.          1.         -1.         -1.          1.        ]
 [ 0.9999995   0.9999998  -1.         -0.9661819  -0.924035  ]]
Y1_val:
 [[ 1.          1.         -1.         -1.          1.        ]
 [ 0.9906206  -0.79206675 -0.99438894 -0.9633575  -0.63100463]
 [ 1.          1.         -1.         -1.          0.9999412 ]
 [ 0.99999976  0.9972692  -1.         -0.9998925   0.21211284]]
'''
